package com.tomtop.controllers.payment;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.fastjson.JSONObject;
import com.tomtop.dto.order.Order;
import com.tomtop.entity.order.PaymentError;
import com.tomtop.entity.payment.paypal.PaymentLogEvent;
import com.tomtop.events.EventBroker;
import com.tomtop.events.order.ReduceQtyEvent;
import com.tomtop.exceptions.BadRequestException;
import com.tomtop.exceptions.UserNoLoginException;
import com.tomtop.forms.PlaceOrderForm;
import com.tomtop.mappers.order.DetailMapper;
import com.tomtop.services.ICurrencyService;
import com.tomtop.services.impl.order.OrderPaymentService;
import com.tomtop.services.order.IOrderService;
import com.tomtop.services.order.IOrderStatusService;
import com.tomtop.services.payment.IPaymentCallbackService;
import com.tomtop.services.payment.IPaymentProvider;
import com.tomtop.services.payment.IPaymentService;
import com.tomtop.services.payment.ocean.OceanPaymentService;
import com.tomtop.utils.FoundationService;
import com.tomtop.utils.Request;
import com.tomtop.valueobjects.Constants;
import com.tomtop.valueobjects.base.LoginContext;
import com.tomtop.valueobjects.order.PaymentContext;
import com.tomtop.valueobjects.payment.ocean.OceanPaymentResult;

@Controller
@RequestMapping("/ocean")
public class OceanController {
	private static final Logger Logger = LoggerFactory
			.getLogger(OceanController.class);
	private static final String REDIRECT = "/payment-result/succeed/ocean/";
	@Autowired
	private OceanPaymentService oceanService;
	@Autowired
	private IPaymentCallbackService callbackService;
	@Autowired
	private IOrderService orderService;
	@Autowired
	private EventBroker eventBroker;

	@Autowired
	FoundationService foundation;

	@Autowired
	private OrderPaymentService orderPaymentService;

	@Autowired
	IPaymentService paymentService;

	@Autowired
	private IOrderStatusService statusService;

	@Autowired
	private IPaymentCallbackService oceanLogService;

	@Autowired
	ICurrencyService currencyService;

	@Autowired
	DetailMapper detailMapper;

	@Value("${payment.oceanEndPoint}")
	String oceanEndPoint;

	@RequestMapping(value = "/return", method = RequestMethod.POST)
	public String userPOST(@ModelAttribute OceanPaymentResult from,
			Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		OceanPaymentResult result = from;
		String orderNum = result.getOrder_number();
		Logger.debug("OceanPayment userPOST orderID: {}, Result: {}", orderNum,
				result);
		String signValue = oceanService
				.getOceanValidSignValue(result, orderNum);

		if (signValue.toLowerCase().equals(result.getSignValue().toLowerCase())) {
			if ("1".equals(result.getPayment_status())
					|| "-1".equals(result.getPayment_status())) {
				int site = foundation.getSiteID();
				// 发送事件去修改库存
				ReduceQtyEvent event = new ReduceQtyEvent(orderNum, site);
				this.eventBroker.post(event);
			}
		}
		Order order = orderService.getOrderByOrderNumber(orderNum);
		if (order == null) {
			throw new BadRequestException("can not found order with orderNum:"
					+ orderNum);
		}
		// 保存订单总金额
		// if (order != null) {
		// List<OrderDetail> dlist = detailMapper
		// .getOrderDetailByOrderId(order.getIid());
		// if ("USD".equals(order.getCcurrency())) {
		// model.put("order", order);
		// model.put("orderDetails", dlist);
		// } else {
		// // 美元总价
		// double usdGrandprice = currencyService.exchange(
		// order.getFgrandtotal(), order.getCcurrency(), "USD");
		// double shipPrice = currencyService.exchange(
		// order.getFshippingprice(), order.getCcurrency(), "USD");
		// double subtotal = currencyService.exchange(
		// order.getFordersubtotal(), order.getCcurrency(), "USD");
		// double extra = currencyService.exchange(order.getFextra(),
		// order.getCcurrency(), "USD");
		// order.setFgrandtotal(usdGrandprice);
		// order.setFshippingprice(shipPrice);
		// order.setFordersubtotal(subtotal);
		// order.setFextra(extra);
		// model.put("order", order);
		// for (OrderDetail od : dlist) {
		// double odprice = currencyService.exchange(od.getFprice(),
		// order.getCcurrency(), "USD");
		// double odtotalprice = currencyService.exchange(
		// od.getFtotalprices(), order.getCcurrency(), "USD");
		// od.setFtotalprices(odtotalprice);
		// od.setFprice(odprice);
		// }
		// model.put("orderDetails", dlist);
		// }
		// }

		if ("1".equals(result.getPayment_status())
				|| "-1".equals(result.getPayment_status())) {
			// model.put("ordernumber", orderNum);
			// LoginContext lc = foundation.getLoginContext();
			// return "/order/pay_success2";

			// 为了广告联盟,需要重定向
			response.sendRedirect(REDIRECT + orderNum);
			return null;
		}
		// else if ("-1".equals(result.getPayment_status())) {
		// model.put("ordernumber", orderNum);
		// return "/order/pay_success2";
		// }

		// 跳到失败页面
		String details = result.getPayment_details();
		String[] str = details.split(":");
		// 跳转到支付失败页面
		StringBuilder errorurl = new StringBuilder("/payment-result/error");
		errorurl.append("?orderNum=").append(orderNum);
		errorurl.append("&errorCode=").append(str[0]);
		errorurl.append("&error=").append(str[1]);
		errorurl.append("&returnWhere=").append("cart");
		errorurl.append("&storageid=").append(order.getIstorageid());
		response.sendRedirect(errorurl.toString());
		return null;
	}

	@RequestMapping(value = "/doPayment", method = RequestMethod.GET)
	public String paymentToGo(String orderNum, HttpServletRequest request,
			HttpServletResponse response, Map<String, Object> model) {
		LoginContext loginCtx = this.foundation.getLoginContext();
		if (loginCtx == null) {
			throw new UserNoLoginException();
		}
		String email = loginCtx.getEmail();

		PaymentContext paymentContext = orderService.getPaymentContext(
				orderNum, foundation.getLanguage());
		Order order = paymentContext.getOrder().getOrder();

		IPaymentProvider provider = paymentService.getPaymentById(order
				.getCpaymentid());
		if (provider.isNeedExtraInfo()) {
			PlaceOrderForm form = orderPaymentService.getForm(
					order.getCordernumber(), order.getCpaymentid());
			paymentContext.setForm(form);
		}
		if (order == null
				|| !order.getCmemberemail().equals(email.toLowerCase())
				&& statusService
						.getIdByName(IOrderStatusService.PAYMENT_PENDING) == order
						.getIstatus()) {
			throw new BadRequestException("order email invalid");
		}
		
		//校验库存
		orderService.validateInventory(order.getIstorageid(),paymentContext.getOrder().getDetails());
		
		Map<String, String> paras = provider.getDoPaymentParas(paymentContext);
		Assert.notEmpty(paras, "create ocean payment paras error");
		// 记录日志
		int site = this.foundation.getSiteID();

		JSONObject json = new JSONObject();
		json.putAll(paras);
		json.put("from", "OceanController.doPayment");

		PaymentLogEvent event = new PaymentLogEvent(site, orderNum,
				json.toJSONString(), null);
		eventBroker.post(event);

		// oceanLogService.insert(orderNum, JSONObject.toJSONString(paras),
		// order.getCpaymentid(), "OceanController.paymentToGo",
		// foundation.getSiteID());

		model.put("form", paras);
		model.put("step", 2);
		model.put("actionUrl", oceanEndPoint);
		
		String host = Request.currentRequest().getHeader(Constants.HOST);
		String[] hostarr = host.split("\\.");
		if(hostarr.length>0 && "m".equals(hostarr[0])){
			return "/mobile/payment/ocean_redirect";
		}else{
			return "/payment/ocean_redirect";
		}
	}
}
